import os
from PySide6.QtWidgets import (
    QWidget, QComboBox, QCheckBox, QLabel, QSizePolicy, QGridLayout
)
from PySide6.QtCore import Qt

from src.config import app_config
from src.ui.constants import SOURCE_LANGUAGES, TARGET_LANGUAGES
from src.translation.openai_translator import OpenAITranslator
from src.translation.microsoft_translator import MicrosoftTranslator
from src.utils.logger import get_logger
from src.ui.i18n import _


class TranslationOptionsWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.logger = get_logger(__name__)
        self.llm_providers = []
        
        self._setup_ui()
        self._connect_signals()
        self.reload_config()
        self.retranslate_ui()

    def _setup_ui(self):
        # Use a robust, standard QGridLayout for perfect alignment and stability.
        self.grid_layout = QGridLayout(self)
        self.grid_layout.setContentsMargins(0, 0, 0, 0)
        self.grid_layout.setSpacing(10)

        # --- Initialize Widgets and Labels ---
        self.translator_combo = QComboBox()
        self.translator_combo.addItems(
            [OpenAITranslator.get_name(), MicrosoftTranslator.get_name()])
        self.provider_combo = QComboBox()
        self.translation_model_combo = QComboBox()
        self.source_lang_combo = QComboBox()
        self.target_lang_combo = QComboBox()
        self.video_type_combo = QComboBox()
        self.translation_style_combo = QComboBox()
        self.no_think_checkbox = QCheckBox()

        self.translator_label = QLabel()
        self.provider_combo_label = QLabel()
        self.model_combo_label = QLabel()
        self.source_lang_label = QLabel()
        self.target_lang_label = QLabel()
        self.video_type_label = QLabel()
        self.translation_style_label = QLabel()

        # --- Add widgets to the grid layout ---
        # Row 0
        self.grid_layout.addWidget(self.translator_label, 0, 0)
        self.grid_layout.addWidget(self.translator_combo, 0, 1)
        self.grid_layout.addWidget(self.source_lang_label, 0, 2)
        self.grid_layout.addWidget(self.source_lang_combo, 0, 3)
        self.grid_layout.addWidget(self.target_lang_label, 0, 4)
        self.grid_layout.addWidget(self.target_lang_combo, 0, 5)

        # Row 1
        self.grid_layout.addWidget(self.provider_combo_label, 1, 0)
        self.grid_layout.addWidget(self.provider_combo, 1, 1)
        self.grid_layout.addWidget(self.model_combo_label, 1, 2)
        self.grid_layout.addWidget(self.translation_model_combo, 1, 3)
        self.grid_layout.addWidget(self.video_type_label, 1, 4)
        self.grid_layout.addWidget(self.video_type_combo, 1, 5)

        # Row 2
        self.grid_layout.addWidget(self.translation_style_label, 2, 0)
        self.grid_layout.addWidget(self.translation_style_combo, 2, 1)
        self.grid_layout.addWidget(self.no_think_checkbox, 2, 2, 1, 2) # Span 1 row, 2 columns

        # Set column stretch factors for responsive behavior
        self.grid_layout.setColumnStretch(1, 1)
        self.grid_layout.setColumnStretch(3, 1)
        self.grid_layout.setColumnStretch(5, 1)
        

    def _connect_signals(self):
        self.translator_combo.currentTextChanged.connect(
            self._update_translator_options)
        self.provider_combo.currentTextChanged.connect(
            self._on_provider_changed)
        self.translation_model_combo.currentIndexChanged.connect(self._on_model_changed)
        self.translation_model_combo.currentIndexChanged.connect(
            self._update_no_think_visibility)

    def reload_config(self):
        self.logger.debug("Reloading config for translation options widget...")
        self._populate_lang_combos()
        self._update_translator_options()
        self._populate_video_types()
        self._populate_translation_styles()

    def retranslate_ui(self):
        self.translator_label.setText(_("Translation Service:"))
        self.source_lang_label.setText(_("Source Language:"))
        self.target_lang_label.setText(_("Target Language:"))
        self.provider_combo_label.setText(_("Service Provider:"))
        self.model_combo_label.setText(_("Model:"))
        self.no_think_checkbox.setText(_("Disable thinking mode (no_think)"))
        self.video_type_label.setText(_("Video Type:"))
        self.translation_style_label.setText(_("Translation Style:"))
        
        self._populate_lang_combos()
        self._populate_video_types()
        self._populate_translation_styles()

    def get_options(self):
        model_config = None
        if self.translator_combo.currentText() == OpenAITranslator.get_name():
            lean_model_config = self.current_model()
            if lean_model_config:
                provider_name = lean_model_config.get("provider_name")
                all_providers = app_config.get("service_providers", [])
                provider_data = next((p for p in all_providers if p.get(
                    "provider_name") == provider_name), None)
                
                if provider_data:
                    service_config = provider_data.get("services", {}).get("llm", {})
                    model_config = {
                        **lean_model_config,
                        "base_url": service_config.get("base_url"),
                        "api_key": provider_data.get("api_key"),
                    }

        return {
            "translator": self.translator_combo.currentText(),
            "source_lang": self.source_lang_combo.currentData(),
            "target_lang": self.target_lang_combo.currentData(),
            "video_type": self.video_type_combo.currentText(),
            "translation_style": self.translation_style_combo.currentText(),
            "no_think": self.no_think_checkbox.isChecked() and self.no_think_checkbox.isVisible(),
            "model_config": model_config,
        }

    def _update_translator_options(self, text=None):
        is_openai = self.translator_combo.currentText() == OpenAITranslator.get_name()
        
        # Set visibility for each widget and its label
        self.provider_combo_label.setVisible(is_openai)
        self.provider_combo.setVisible(is_openai)
        self.model_combo_label.setVisible(is_openai)
        self.translation_model_combo.setVisible(is_openai)
        self.video_type_label.setVisible(is_openai)
        self.video_type_combo.setVisible(is_openai)
        self.translation_style_label.setVisible(is_openai)
        self.translation_style_combo.setVisible(is_openai)

        if is_openai:
            self._reload_model_config()
            self._set_last_used_model()
        
        self._update_no_think_visibility()

        if text:
            app_config.set("translation.last_used_translator",
                           text, emit_signal=False)

    def _update_no_think_visibility(self):
        is_openai = self.translator_combo.currentText() == OpenAITranslator.get_name()
        if not is_openai:
            self.no_think_checkbox.setVisible(False)
            return

        selected_model_data = self.current_model()
        supports_no_think = selected_model_data.get(
            "supports_no_think", False) if selected_model_data else False
        self.no_think_checkbox.setVisible(supports_no_think)

    def _on_model_changed(self, index=None):
        self._update_no_think_visibility()
        model_data = self.current_model()
        if model_data:
            app_config.set("translation.last_used_openai_model",
                           model_data, emit_signal=False)
            app_config.save(emit_signal=False)

    def _on_provider_changed(self, provider_name):
        self._update_models_for_provider(provider_name)
        self._on_model_changed()

    def _populate_lang_combos(self):
        current_source = self.source_lang_combo.currentData()
        current_target = self.target_lang_combo.currentData()

        self.source_lang_combo.clear()
        self.target_lang_combo.clear()

        for code, name in SOURCE_LANGUAGES.items():
            display = f"{_(name)} ({code})"
            self.source_lang_combo.addItem(display, code)

        for code, name in TARGET_LANGUAGES.items():
            display = f"{_(name)} ({code})"
            self.target_lang_combo.addItem(display, code)

        source_code = current_source or app_config.get(
            "translation.default_source_lang", "en")
        target_code = current_target or app_config.get(
            "translation.default_target_lang", "zh-CN")

        source_index = self.source_lang_combo.findData(source_code)
        if source_index != -1:
            self.source_lang_combo.setCurrentIndex(source_index)

        target_index = self.target_lang_combo.findData(target_code)
        if target_index != -1:
            self.target_lang_combo.setCurrentIndex(target_index)

    def _populate_video_types(self):
        current_text = self.video_type_combo.currentText()
        self.video_type_combo.clear()
        items = app_config.get("translation.video_types", [])
        self.video_type_combo.addItems([_(item) for item in items])
        index = self.video_type_combo.findText(current_text)
        if index != -1:
            self.video_type_combo.setCurrentIndex(index)

    def _populate_translation_styles(self):
        current_text = self.translation_style_combo.currentText()
        self.translation_style_combo.clear()
        items = app_config.get("translation.translation_styles", [])
        self.translation_style_combo.addItems([_(item) for item in items])
        index = self.translation_style_combo.findText(current_text)
        if index != -1:
            self.translation_style_combo.setCurrentIndex(index)

    def current_model(self):
        return self.translation_model_combo.currentData()

    def _reload_model_config(self):
        all_providers = app_config.get("service_providers", [])
        self._update_model_providers(all_providers)

    def _update_model_providers(self, providers_data):
        self.provider_combo.blockSignals(True)
        self.translation_model_combo.blockSignals(True)
        try:
            self.provider_combo.clear()
            self.translation_model_combo.clear()
            self.llm_providers = [
                p for p in providers_data
                if p.get("enabled") and "llm" in p.get("services", {})
            ]
            for provider in self.llm_providers:
                self.provider_combo.addItem(
                    provider.get("provider_name", "Unknown"))
        finally:
            self.provider_combo.blockSignals(False)
            self.translation_model_combo.blockSignals(False)
        
        self.provider_combo.blockSignals(True)
        self._update_models_for_provider(self.provider_combo.currentText())
        self.provider_combo.blockSignals(False)

    def _update_models_for_provider(self, provider_name):
        self.translation_model_combo.blockSignals(True)
        try:
            self.translation_model_combo.clear()
            provider_data = next((p for p in self.llm_providers if p.get(
                "provider_name") == provider_name), None)
            if provider_data:
                service_data = provider_data.get("services", {}).get("llm", {})
                models = service_data.get("models", [])
                for model in models:
                    model_name = model.get("model_name")
                    display_name = model.get("display_name")
                    if not display_name or display_name == model_name:
                        display_name = model_name.split('/')[-1]
                    lean_model_config = {
                        "provider_name": provider_data.get("provider_name"),
                        **model
                    }
                    self.translation_model_combo.addItem(
                        display_name, userData=lean_model_config)
        finally:
            self.translation_model_combo.blockSignals(False)
        self._update_no_think_visibility()

    def _set_last_used_model(self):
        self.provider_combo.blockSignals(True)
        self.translation_model_combo.blockSignals(True)
        try:
            last_model_config = app_config.get(
                "translation.last_used_openai_model")
            if not last_model_config: return
            provider_name = last_model_config.get("provider_name")
            model_name = last_model_config.get("model_name")
            if not provider_name or not model_name: return

            for i in range(self.provider_combo.count()):
                if self.provider_combo.itemText(i) == provider_name:
                    self.provider_combo.setCurrentIndex(i)
                    self._update_models_for_provider(provider_name)
                    for j in range(self.translation_model_combo.count()):
                        model_data = self.translation_model_combo.itemData(j)
                        if model_data and model_data.get("model_name") == model_name:
                            self.translation_model_combo.setCurrentIndex(j)
                            return
        finally:
            self.provider_combo.blockSignals(False)
            self.translation_model_combo.blockSignals(False)

    def set_target_language(self, lang_code):
        if not lang_code:
            return
        index = self.target_lang_combo.findData(lang_code)
        if index != -1:
            self.target_lang_combo.setCurrentIndex(index)
